﻿using Microsoft.EntityFrameworkCore;
using MyMes.Infrastructure;
using MyMES.Dto;
using MyMES.IServices.MeadingManage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using VOL.Core.Extensions;
using VOL.Core.Utilities.Response;
using VOL.Entity.DomainModels;
using VOL.Entity.DomainModels.Core;
using VOL.Entity.MeadingManage;

namespace MyMES.Services.MeadingManage
{
    /// <summary>
    /// 生产报工服务类，提供生产报工相关的业务操作
    /// </summary>
    public class MeadingReportService : IMeadingReportService
    {
        private readonly IBaseRepository<MeadingReport> _meadingReportRepository;
        private readonly IBaseRepository<Workstation> _workStationRepository;
        private readonly IBaseRepository<MaterialProduct> _materialProductRepository;
        private readonly IBaseRepository<WorkOrder> _workOrderRepository;
        private readonly IBaseRepository<Sys_Department> _departmentRepository;
        private readonly IBaseRepository<Sys_User> _userRepository;
        private readonly IBaseRepository<Sys_UserDepartment> _userDepartmentRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="meadingReportRepository">生产报工仓储接口</param>
        public MeadingReportService(IBaseRepository<MeadingReport> meadingReportRepository,
                                    IBaseRepository<Workstation> workStationRepository,
                                    IBaseRepository<MaterialProduct> materialProductRepository,
                                    IBaseRepository<WorkOrder> workOrderRepository,
                                    IBaseRepository<Sys_Department> departmentRepository,
                                    IBaseRepository<Sys_User> userRepository,
                                    IBaseRepository<Sys_UserDepartment> userDepartmentRepository)
        {
            _meadingReportRepository = meadingReportRepository;
            _workStationRepository = workStationRepository;
            _materialProductRepository = materialProductRepository;
            _workOrderRepository = workOrderRepository;
            _departmentRepository = departmentRepository;
            _userRepository = userRepository;
            _userDepartmentRepository = userDepartmentRepository;
        }

        /// <summary>
        /// 添加生产报工
        /// </summary>
        /// <param name="meadingReport">生产报工实体</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> AddMeadingRepot(MeadingReport meadingReport)
        {
            WebResponseContent response = new WebResponseContent();
            try
            {
                // 自动生成报工编号
                if (string.IsNullOrEmpty(meadingReport.ReportCode))
                {
                    meadingReport.ReportCode = await GenerateReportCodeAsync();
                }
                else
                {
                    // 检查报工编号是否已存在
                    bool exists = await _meadingReportRepository.GetAll()
                        .AnyAsync(x => x.ReportCode == meadingReport.ReportCode);

                    if (exists)
                    {
                        return response.Error("报工编号已存在");
                    }
                }

                // 设置默认报工日期
                if (meadingReport.ReportDate == default)
                {
                    meadingReport.ReportDate = DateTime.Now;
                }

                // 保存数据
                await _meadingReportRepository.AddAsync(meadingReport);
                return response.OK("添加报工记录成功");
            }
            catch (Exception ex)
            {
                return response.Error($"添加报工记录失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 生成报工编号
        /// </summary>
        /// <returns>生成的报工编号</returns>
        private async Task<string> GenerateReportCodeAsync()
        {
            // 生成格式: RPT + 年月日 + 3位序号，例如: RPT20240620001
            string datePrefix = $"RPT{DateTime.Now:yyyyMMdd}";

            // 查询当天最大编号
            var maxCodeToday = await _meadingReportRepository.GetAll()
                .Where(x => x.ReportCode.StartsWith(datePrefix))
                .Select(x => x.ReportCode)
                .OrderByDescending(x => x)
                .FirstOrDefaultAsync();

            int sequence = 1;
            if (!string.IsNullOrEmpty(maxCodeToday))
            {
                // 提取序列号部分并递增
                if (int.TryParse(maxCodeToday.Substring(datePrefix.Length), out int currentSequence))
                {
                    sequence = currentSequence + 1;
                }
            }

            // 生成新编号，确保3位数字序号
            return $"{datePrefix}{sequence:D3}";
        }

        /// <summary>
        /// 删除生产报工
        /// </summary>
        /// <param name="ids">生产报工ID列表，以逗号分隔的字符串</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> DelMeadingRepot(string ids)
        {
            WebResponseContent response = new WebResponseContent();
            try
            {
                if (string.IsNullOrEmpty(ids))
                {
                    return response.Error("未选择要删除的记录");
                }

                // 将逗号分隔的字符串转换为整数ID列表
                List<int> idList = new List<int>();
                foreach (var id in ids.Split(','))
                {
                    if (int.TryParse(id, out int parsedId))
                    {
                        idList.Add(parsedId);
                    }
                }

                if (idList.Count == 0)
                {
                    return response.Error("无效的ID格式");
                }

                // 执行删除
                Expression<Func<MeadingReport, bool>> expression = e => idList.Contains(e.Id);
                int result = await _meadingReportRepository.DelAll(expression);

                if (result > 0)
                {
                    return response.OK($"成功删除{result}条记录");
                }
                else
                {
                    return response.Error("删除失败");
                }
            }
            catch (Exception ex)
            {
                return response.Error($"删除报工记录失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 获取生产报工列表
        /// </summary>
        /// <param name="dto">查询参数</param>
        /// <returns>分页数据</returns>
        public async Task<PageGridData<MeadingRepotDto>> GetMeadingRepot(GetMeadingRepotDto dto)
        {
            try
            {
                // 初始化三表联查，先获取所有数据
                var query = from report in _meadingReportRepository.GetAll()
                            join workStation in _workStationRepository.GetAll()
                            on report.WorkStation equals workStation.WorkCode into wsJoin
                            from ws in wsJoin.DefaultIfEmpty()
                            join material in _materialProductRepository.GetAll()
                            on report.ProductCode equals material.MaterialCode into mpJoin
                            from mp in mpJoin.DefaultIfEmpty()
                            select new { Report = report, WorkStation = ws, Material = mp };

                // 先查询所有数据并转换为DTO
                var allResults = await query
                    .OrderByDescending(x => x.Report.Id)
                    .Select(x => new MeadingRepotDto
                    {
                        Id = x.Report.Id,
                        ReportCode = x.Report.ReportCode,
                        ReportType = x.Report.ReportType,
                        WorkStation = x.Report.WorkStation,
                        WorkStationName = x.WorkStation != null ? x.WorkStation.WorkStationName : x.Report.WorkStation,
                        Process = x.Report.Process,
                        MeadingCode = x.Report.MeadingCode,
                        ProductCode = x.Report.ProductCode,
                        MaterialCode = x.Report.ProductCode,
                        MaterialName = x.Material != null ? x.Material.MaterialName : "",
                        Color = x.Report.Color,
                        Size = x.Report.Size,
                        Num = x.Report.Num,
                        Reporter = x.Report.Reporter,
                        ReportDate = x.Report.ReportDate,
                        CheckMan = x.Report.CheckMan,
                        Descs = x.Report.Descs,
                        Status = x.Report.Status
                    })
                    .ToListAsync();

                // 在内存中对DTO集合应用筛选条件
                var filteredResults = allResults.AsQueryable();

                if (!string.IsNullOrEmpty(dto.ReportType))
                    filteredResults = filteredResults.Where(x => x.ReportType.Contains(dto.ReportType));

                if (!string.IsNullOrEmpty(dto.WorkStationName))
                    filteredResults = filteredResults.Where(x => x.WorkStationName.Contains(dto.WorkStationName));

                if (!string.IsNullOrEmpty(dto.MeadingCode))
                    filteredResults = filteredResults.Where(x => x.MeadingCode.Contains(dto.MeadingCode));

                if (!string.IsNullOrEmpty(dto.MaterialCode))
                    filteredResults = filteredResults.Where(x => x.MaterialCode.Contains(dto.MaterialCode));

                if (!string.IsNullOrEmpty(dto.MaterialName))
                    filteredResults = filteredResults.Where(x => !string.IsNullOrEmpty(x.MaterialName) && x.MaterialName.Contains(dto.MaterialName));

                if (!string.IsNullOrEmpty(dto.Reporter))
                    filteredResults = filteredResults.Where(x => x.Reporter.Contains(dto.Reporter));

                if (!string.IsNullOrEmpty(dto.CheckMan))
                    filteredResults = filteredResults.Where(x => !string.IsNullOrEmpty(x.CheckMan) && x.CheckMan.Contains(dto.CheckMan));

                if (dto.Status.HasValue)
                    filteredResults = filteredResults.Where(x => x.Status == dto.Status.Value);

                // 计算过滤后的总记录数
                int totalCount = filteredResults.Count();

                // 应用分页
                var pagedResults = filteredResults
                    .Skip((dto.PageIndex - 1) * dto.PageSize)
                    .Take(dto.PageSize)
                    .ToList();

                // 返回分页数据
                return new PageGridData<MeadingRepotDto>
                {
                    rows = pagedResults,
                    total = totalCount
                };
            }
            catch (Exception ex)
            {
                throw new Exception($"获取报工列表失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 更新生产报工
        /// </summary>
        /// <param name="meadingReport">生产报工实体</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> UpdMeadingRepot(MeadingReport meadingReport)
        {
            WebResponseContent response = new WebResponseContent();
            try
            {
                // 验证数据
                if (meadingReport == null)
                {
                    return response.Error("更新数据不能为空");
                }

                if (string.IsNullOrEmpty(meadingReport.ReportCode))
                {
                    return response.Error("报工编号不能为空");
                }

                if (string.IsNullOrEmpty(meadingReport.MeadingCode))
                {
                    return response.Error("报工编码不能为空");
                }

                if (string.IsNullOrEmpty(meadingReport.Reporter))
                {
                    return response.Error("报工人不能为空");
                }

                // 检查报工记录是否存在
                var existingReport = await _meadingReportRepository.FindAsync(meadingReport.Id);
                if (existingReport == null)
                {
                    return response.Error("报工记录不存在");
                }

                // 检查报工编号是否已被其他记录使用
                bool exists = await _meadingReportRepository.GetAll()
                    .AnyAsync(x => x.ReportCode == meadingReport.ReportCode && x.Id != meadingReport.Id);

                if (exists)
                {
                    return response.Error("报工编号已被其他记录使用");
                }

                // 更新数据
                await _meadingReportRepository.UpdateAsync(meadingReport);
                return response.OK("更新报工记录成功");
            }
            catch (Exception ex)
            {
                return response.Error($"更新报工记录失败：{ex.Message}");
            }
        }

        public async Task<PageGridData<WorkOrder>> GetWorkOrder(GetWorkOrderDto dto)
        {
            try
            {
                // 获取所有工单数据
                var query = _workOrderRepository.GetAll();

                // 应用筛选条件
                if (!string.IsNullOrEmpty(dto.WorkOrderCode))
                    query = query.Where(x => x.WorkOrderCode.Contains(dto.WorkOrderCode));

                if (!string.IsNullOrEmpty(dto.WorkOrderName))
                    query = query.Where(x => x.WorkOrderName.Contains(dto.WorkOrderName));

                if (!string.IsNullOrEmpty(dto.ProductCode))
                    query = query.Where(x => x.ProductNumber.Contains(dto.ProductCode));

                if (!string.IsNullOrEmpty(dto.ProductName))
                    query = query.Where(x => x.ProductName.Contains(dto.ProductName));

                if (!string.IsNullOrEmpty(dto.CustmorName))
                    query = query.Where(x => x.ClientName.Contains(dto.CustmorName));

                // 计算总记录数
                int totalCount = await query.CountAsync();

                // 应用分页和排序
                var pagedResults = await query
                    .OrderByDescending(x => x.Id)
                    .Skip((dto.PageIndex - 1) * dto.PageSize)
                    .Take(dto.PageSize)
                    .ToListAsync();

                // 返回分页数据
                return new PageGridData<WorkOrder>
                {
                    rows = pagedResults,
                    total = totalCount
                };
            }
            catch (Exception ex)
            {
                throw new Exception($"获取工单列表失败：{ex.Message}");
            }
        }

        public async Task<WebResponseContent> GetWorkStation()
        {
            WebResponseContent response = new WebResponseContent();
            try
            {
                response.Data = _workOrderRepository.GetAll();
                response.OK("查询成功");
                return response;
            }
            catch (Exception ex)
            {
                return response.Error($"获取工作站数据失败：{ex.Message}");
            }
        }

        public async Task<WebResponseContent> GetDepartmentsList()
        {
            WebResponseContent response = new WebResponseContent();
            try
            {
                // 获取所有部门列表
                var departments = await _departmentRepository.GetAll().ToListAsync();
                
                if (departments == null || departments.Count == 0)
                {
                    return response.OK("暂无部门数据", new List<DepartmentDto>());
                }
                
                // 将部门转换为字典，便于查找
                var deptDict = departments.ToDictionary(d => d.DepartmentId);
                
                // 先创建所有部门的DTO对象字典
                var deptDtoDict = new Dictionary<Guid, DepartmentDto>();
                foreach (var dept in departments)
                {
                    var deptDto = new DepartmentDto
                    {
                        DepartmentId = dept.DepartmentId.ToString(),
                        DepartmentName = dept.DepartmentName,
                        Children = new List<DepartmentDto>()
                    };
                    deptDtoDict[dept.DepartmentId] = deptDto;
                }
                
                // 创建根部门列表
                List<DepartmentDto> rootDepartments = new List<DepartmentDto>();
                
                // 构建部门树结构
                foreach (var dept in departments)
                {
                    // 如果是根部门（没有父部门），则添加到根部门列表
                    if (dept.ParentId == null)
                    {
                        rootDepartments.Add(deptDtoDict[dept.DepartmentId]);
                    }
                    // 否则添加到父部门的子部门列表
                    else if (deptDict.ContainsKey(dept.ParentId.Value) && deptDtoDict.ContainsKey(dept.ParentId.Value))
                    {
                        deptDtoDict[dept.ParentId.Value].Children.Add(deptDtoDict[dept.DepartmentId]);
                    }
                    // 如果找不到父部门，则也作为根部门处理
                    else
                    {
                        rootDepartments.Add(deptDtoDict[dept.DepartmentId]);
                    }
                }
                
                // 直接将数据传递给OK方法，不要单独设置Data属性
                return response.OK($"获取部门列表成功，共{rootDepartments.Count}个根部门", rootDepartments);
            }
            catch (Exception ex)
            {
                return response.Error($"获取部门列表失败：{ex.Message}");
            }
        }

        public async Task<WebResponseContent> GetUserList(string? useName, string? phone, string? departmentId)
        {
            WebResponseContent response = new WebResponseContent();
            try
            {
                // 构建基础查询
                var query = _userRepository.GetAll();

                // 使用 WhereIf 应用条件过滤
                query = query.WhereIF(!string.IsNullOrEmpty(useName), u => u.UserName.Contains(useName) || u.UserTrueName.Contains(useName))
                             .WhereIF(!string.IsNullOrEmpty(phone), u => u.PhoneNo.Contains(phone));

                // 如果指定了部门ID，则筛选该部门下的用户
                if (!string.IsNullOrEmpty(departmentId) && Guid.TryParse(departmentId, out Guid deptId))
                {
                    try 
                    {
                        // 通过用户-部门关联表筛选
                        var userIdsInDept = await _userDepartmentRepository.GetAll()
                            .Where(ud => ud.DepartmentId == deptId)
                            .Select(ud => ud.UserId)
                            .ToListAsync();

                        if (userIdsInDept.Any())
                        {
                            query = query.Where(u => userIdsInDept.Contains(u.User_Id));
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"获取部门用户异常: {ex.Message}");
                        // 查询异常时不应用部门筛选，继续获取所有用户
                    }
                }

                // 执行查询
                var users = await query
                    .OrderBy(u => u.User_Id)
                    .ToListAsync();

                // 直接将数据传递给OK方法，不要单独设置Data属性
                return response.OK($"获取用户列表成功，共{users.Count}个用户", users);
            }
            catch (Exception ex)
            {
                return response.Error($"获取用户列表失败：{ex.Message}");
            }
        }
    }
}
